library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use ieee.std_logic_arith.all;

entity transmit is
PORT
	(
--		Interface to PHY
		TX_EN,TX_ER		: OUT STD_LOGIC ;
		q_sig			: OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
		rdclk_sig		: IN STD_LOGIC ;
		reset_sig		: IN std_logic;				
-- 		Length FIF signals to SF				
		wrreq_sig_L		:IN STD_LOGIC;
		data_sig_L:  STD_LOGIC_VECTOR (11 DOWNTO 0);			
--		Data FIFO signals to SF		
		data_sig		: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
		wrclk_sig		: IN STD_LOGIC ;
		wrreq_sig		: IN STD_LOGIC ;		
		wrusedw_sig		: OUT STD_LOGIC_VECTOR (12 DOWNTO 0)
		
	);

end transmit;

architecture main of transmit is
--------------------data_FIFO-----------------------------
	COMPONENT FIFO_Data
	PORT (
		aclr		: IN STD_LOGIC;
		data		: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
		rdclk		: IN STD_LOGIC ;
		rdreq		: IN STD_LOGIC ;
		wrclk		: IN STD_LOGIC ;
		wrreq		: IN STD_LOGIC ;
		q		: OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
		rdempty		: OUT STD_LOGIC ;
		rdfull		: OUT STD_LOGIC ;
		rdusedw		: OUT STD_LOGIC_VECTOR (13 DOWNTO 0);
		wrempty		: OUT STD_LOGIC ;
		wrfull		: OUT STD_LOGIC ;
		wrusedw		: OUT STD_LOGIC_VECTOR (12 DOWNTO 0)
	);
	END COMPONENT;
--------------------------Length_FIFO----------------------
	COMPONENT length_FIFO
	PORT
	(
		aclr		: IN STD_LOGIC;
		data		: IN STD_LOGIC_VECTOR (11 DOWNTO 0);
		rdclk		: IN STD_LOGIC ;
		rdreq		: IN STD_LOGIC ;
		wrclk		: IN STD_LOGIC ;
		wrreq		: IN STD_LOGIC ;
		q		: OUT STD_LOGIC_VECTOR (11 DOWNTO 0);
		rdempty		: OUT STD_LOGIC ;
		rdfull		: OUT STD_LOGIC ;
		wrempty		: OUT STD_LOGIC ;
		wrfull		: OUT STD_LOGIC 
	);
	END COMPONENT;
-----------------------------------------------------------	

type state is (idle,preamble,data,interframe,reset);
signal state_reg: state;
signal preamble_reg: std_logic_vector(63 downto 0);
signal qt: std_logic_vector(3 downto 0);
signal rdreq: STD_LOGIC;
signal counter:std_logic_vector(11 downto 0);
signal length_counter:std_logic_vector(11 downto 0);
-----------------------------------------------------------

signal		rdclk_sig_L:  STD_LOGIC ;
signal		rdreq_sig_L:  STD_LOGIC ;
signal		wrclk_sig_L:  STD_LOGIC ;
signal		q_sig_L:  STD_LOGIC_VECTOR (11 DOWNTO 0);
signal		rdempty_sig_L:  STD_LOGIC ;
signal 		gap_counter : std_logic_vector(7 downto 0);
signal		rdempty_sig	: STD_LOGIC ;
signal		wrempty_sig_L		:  STD_LOGIC ;
signal 		aclr_sig		: STD_LOGIC;
signal 		aclr_sig_L		: STD_LOGIC;	
begin
-----------------------------------------
FIFO_Data_inst : FIFO_Data PORT MAP (	
		aclr	 => aclr_sig,
		data	 => data_sig,
		rdclk	 => rdclk_sig,
		rdreq	 => rdreq,
		wrclk	 => wrclk_sig,
		wrreq	 => wrreq_sig,
		q	 => qt,
		rdempty	 => rdempty_sig,
		rdfull	 => open, --rdfull_sig,
		rdusedw	 => open, --rdusedw_sig,
		wrempty	 => open, --wrempty_sig,
		wrfull	 => open, --wrfull_sig,		
		wrusedw	 => wrusedw_sig		
	);
------------------------------------------

length_FIFO_inst : length_FIFO PORT MAP (
		aclr	 => aclr_sig_L,
		data	 => data_sig_L,
		rdclk	 => rdclk_sig_L,
		rdreq	 => rdreq_sig_L,
		wrclk	 => wrclk_sig_L,
		wrreq	 => wrreq_sig_L,
		q	 => q_sig_L,
		rdempty	 => open, --rdempty_sig_L,
		rdfull	 => open, --rdfull_sig_L,
		wrempty	 => wrempty_sig_L,
		wrfull	 => open --wrfull_sig_L		
	);
	
----------------------------------------	
rdclk_sig_L<=rdclk_sig;
wrclk_sig_L<=wrclk_sig;

------------------------------------------------

process(rdclk_sig,reset_sig)
begin
if(reset_sig='1') then
		
		state_reg <= idle;
		aclr_sig<='1';
		aclr_sig_L<='1';
		
elsif(rdclk_sig'event and rdclk_sig='1') then
		aclr_sig<='0';
		aclr_sig_L<='0';	
		
case state_reg is

				when idle =>
				
					if wrempty_sig_L = '0' then
						state_reg <= preamble;							
					else
						state_reg <= idle;
						rdreq_sig_L<='0';
					end if;
					counter<=x"000";
					TX_EN<='0';
					rdreq<='0';
					preamble_reg<=x"D555555555555555";							
					TX_ER<='0';
				when preamble =>
				
					if(rdempty_sig='0') then
						
							if(preamble_reg(3 downto 0)=x"D") then
								state_reg <= data;	
								q_sig<=preamble_reg(3 downto 0);												
							else
								state_reg <= preamble;
								rdreq<='0';
								q_sig<=preamble_reg(3 downto 0);		
								preamble_reg <= preamble_reg(3 downto 0) & preamble_reg(63 downto 4);						
							end if;
						if(preamble_reg(23 downto 20)=x"D") then
							rdreq_sig_L<='1';
						end if;
						if(preamble_reg(19 downto 16)=x"D") then							
						rdreq_sig_L<='0';
						end if;						
						if(preamble_reg(15 downto 12)=x"D") then
						length_counter<=q_sig_L(10 downto 0) &q_sig_L(11);							
						rdreq_sig_L<='0';
						end if;
						
						TX_EN<='1';
						if(preamble_reg(7 downto 4)=x"D" and length_counter>x"000") then
						rdreq<='1';
						length_counter(0)<='0';
						end if;
					else
						state_reg <=reset;
						TX_EN<='0';
						TX_ER<='1';
					end if;					
				when data =>
				
							if (counter=length_counter) then					
								state_reg <= interframe;
								rdreq<='0';
								length_counter<=x"000";
								q_sig<=x"0";
								TX_EN<='0';	
							elsif (counter=(length_counter-2) or counter=(length_counter-1)) then					
								rdreq<='0';
								q_sig<=qt;
								counter<=counter+1;							
								state_reg<=data;
							elsif (counter<(length_counter-2)) then			
								
								if(rdempty_sig='0') then
										q_sig<=qt;
										counter<=counter+1;							
										state_reg<=data;
										rdreq<='1';	
								else
								state_reg <= reset;
								TX_ER<='1';											
								end if;
								
							end if;
							
				when interframe =>
						if(gap_counter=x"18") then
						state_reg <= reset;
						gap_counter<=x"00";
						else
						gap_counter<=gap_counter+1;		
						state_reg <= interframe;
						end if;
						rdreq<='0';
				when reset =>

					state_reg <= idle;
					rdreq<='0';
					
	end case;		
 end if;		
		
		
end process;

		
end main;